home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet multimedia
/
Muzyka
/
Edytory sampli (probek dzwieku)
/
ZynAddSubFX_2.2.0
/
Setup_ZynAddSubFX-2.2.0.exe
/
source code
/
Effects
/
Echo.C
< prev
next >
Wrap
C/C++ Source or Header
|
2005-03-14
|
5KB
|
241 lines
/*
ZynAddSubFX - a software synthesizer
Echo.C - Echo effect
Copyright (C) 2002-2005 Nasca Octavian Paul
Author: Nasca Octavian Paul
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License (version 2) for more details.
You should have received a copy of the GNU General Public License (version 2)
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Echo.h"
Echo::Echo(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){
efxoutl=efxoutl_;
efxoutr=efxoutr_;
filterpars=NULL;
insertion=insertion_;
//default values
Ppreset=0;
Pvolume=50;
Ppanning=64;
Pdelay=60;
Plrdelay=100;
Plrcross=100;
Pfb=40;
Phidamp=60;
ldelay=NULL;
rdelay=NULL;
lrdelay=0;
setpreset(Ppreset);
cleanup();
};
Echo::~Echo(){
delete[] ldelay;
delete[] rdelay;
};
/*
* Cleanup the effect
*/
void Echo::cleanup(){
int i;
for (i=0;i<dl;i++) ldelay[i]=0.0;
for (i=0;i<dr;i++) rdelay[i]=0.0;
oldl=0.0;
oldr=0.0;
};
/*
* Initialize the delays
*/
void Echo::initdelays(){
kl=0;kr=0;
dl=delay-lrdelay;if (dl<1) dl=1;
dr=delay+lrdelay;if (dr<1) dr=1;
if (ldelay!=NULL) delete [] ldelay;
if (rdelay!=NULL) delete [] rdelay;
ldelay=new REALTYPE[dl];
rdelay=new REALTYPE[dr];
cleanup();
};
/*
* Effect output
*/
void Echo::out(REALTYPE *smpsl,REALTYPE *smpsr){
int i;
REALTYPE l,r,ldl,rdl;
for (i=0;i<SOUND_BUFFER_SIZE;i++){
ldl=ldelay[kl];
rdl=rdelay[kr];
l=ldl*(1.0-lrcross)+rdl*lrcross;
r=rdl*(1.0-lrcross)+ldl*lrcross;
ldl=l;rdl=r;
efxoutl[i]=ldl*2.0;
efxoutr[i]=rdl*2.0;
ldl=smpsl[i]*panning-ldl*fb;
rdl=smpsr[i]*(1.0-panning)-rdl*fb;
//LowPass Filter
ldelay[kl]=ldl=ldl*hidamp+oldl*(1.0-hidamp);
rdelay[kr]=rdl=rdl*hidamp+oldr*(1.0-hidamp);
oldl=ldl;
oldr=rdl;
if (++kl>=dl) kl=0;
if (++kr>=dr) kr=0;
};
};
/*
* Parameter control
*/
void Echo::setvolume(unsigned char Pvolume){
this->Pvolume=Pvolume;
if (insertion==0) {
outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0;
volume=1.0;
} else {
volume=outvolume=Pvolume/127.0;
};
if (Pvolume==0) cleanup();
};
void Echo::setpanning(unsigned char Ppanning){
this->Ppanning=Ppanning;
panning=(Ppanning+0.5)/127.0;
};
void Echo::setdelay(unsigned char Pdelay){
this->Pdelay=Pdelay;
delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec
initdelays();
};
void Echo::setlrdelay(unsigned char Plrdelay){
REALTYPE tmp;
this->Plrdelay=Plrdelay;
tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE;
if (Plrdelay<64.0) tmp=-tmp;
lrdelay=(int) tmp;
initdelays();
};
void Echo::setlrcross(unsigned char Plrcross){
this->Plrcross=Plrcross;
lrcross=Plrcross/127.0*1.0;
};
void Echo::setfb(unsigned char Pfb){
this->Pfb=Pfb;
fb=Pfb/128.0;
};
void Echo::sethidamp(unsigned char Phidamp){
this->Phidamp=Phidamp;
hidamp=1.0-Phidamp/127.0;
};
void Echo::setpreset(unsigned char npreset){
const int PRESET_SIZE=7;
const int NUM_PRESETS=9;
unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
//Echo 1
{67,64,35,64,30,59,0},
//Echo 2
{67,64,21,64,30,59,0},
//Echo 3
{67,75,60,64,30,59,10},
//Simple Echo
{67,60,44,64,30,0,0},
//Canyon
{67,60,102,50,30,82,48},
//Panning Echo 1
{67,64,44,17,0,82,24},
//Panning Echo 2
{81,60,46,118,100,68,18},
//Panning Echo 3
{81,60,26,100,127,67,36},
//Feedback Echo
{62,64,28,64,100,90,55}};
if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;
for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]);
if (insertion!=0) changepar(0,presets[npreset][0]/2);//lower the volume if this is insertion effect
Ppreset=npreset;
};
void Echo::changepar(int npar,unsigned char value){
switch (npar){
case 0: setvolume(value);
break;
case 1: setpanning(value);
break;
case 2: setdelay(value);
break;
case 3: setlrdelay(value);
break;
case 4: setlrcross(value);
break;
case 5: setfb(value);
break;
case 6: sethidamp(value);
break;
};
};
unsigned char Echo::getpar(int npar){
switch (npar){
case 0: return(Pvolume);
break;
case 1: return(Ppanning);
break;
case 2: return(Pdelay);
break;
case 3: return(Plrdelay);
break;
case 4: return(Plrcross);
break;
case 5: return(Pfb);
break;
case 6: return(Phidamp);
break;
};
return(0);//in case of bogus parameter number
};